package programs.statement;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;

import programs.expression.implementedClasses.*;

public class SequenceOfStatements extends ComposedStatement {
	
	private final List<Statement> subStatements = new ArrayList<Statement>();

	public SequenceOfStatements() {
		
	}
	
	public SequenceOfStatements(List<Statement> statements) {
		for(Statement sub : statements) {
			addSubStatement(sub);
		}
	}
	
	public Statement getSubStatementAt(int index) throws IndexOutOfBoundsException {
		if(index < 1 || index > getNbOfSubStatements())
			throw new IndexOutOfBoundsException();
		else 
			return getAllSubStatements().get(index - 1);
	}
	
	protected void setSubStatementAt(int index, Statement subStatement)
			throws IndexOutOfBoundsException {
		if(index < 1 || index > getNbOfSubStatements())
			throw new IndexOutOfBoundsException();
		else
			getAllSubStatements().set(index, subStatement);
	}
	
	public void addSubStatement(Statement subStatement) {
		getAllSubStatements().add(subStatement);
	}
	
	public int getNbOfSubStatements()  {
		return getAllSubStatements().size();
	}

	@Override
	public Set<Variable> getVariables(){
		Set<Variable> set = new HashSet<Variable>();
		for(Statement statement : getAllSubStatements()) {
			set.addAll(statement.getVariables());
		}
		return set;
	}
	
	@Override
	public List<Statement> getAllSubStatements() {
		return this.subStatements;
	}

	@Override
	public Iterator<BasicStatement> getIterator() {
		return new Iterator<BasicStatement>()  {

			private int indexOfCurrentIterator = 1;
			private Iterator<BasicStatement> currentIterator; 

			
			{ 
				if(isEmpty())
				currentIterator = null;
				else
				currentIterator =  getSubStatementAt(1).getIterator();
			}
		
			public boolean hasNext() {
				if(currentIterator == null)
					return false;
				if(currentIterator.hasNext())
					return true;
				for(int i = indexOfCurrentIterator+1; i<=getNbOfSubStatements(); i++) {
					Iterator<BasicStatement> iterator = getSubStatementAt(i).getIterator();
					if(iterator.hasNext())
						return true;
				}				
				return false;
			}

			public BasicStatement next() throws NoSuchElementException {
				if(!hasNext())
					throw new NoSuchElementException();
				if(currentIterator.hasNext())
					return currentIterator.next();
				for(int i = indexOfCurrentIterator+1; i<=getNbOfSubStatements(); i++) {
					currentIterator = getSubStatementAt(i).getIterator();
					if(currentIterator.hasNext()) {
						indexOfCurrentIterator = i;
						return currentIterator.next();
					}
				}
				assert(false);
				return null;
			}

			public void remove() throws UnsupportedOperationException {
				throw new UnsupportedOperationException();
			}
		};
	}
	
	
}
